using System;
using System.Collections.Generic;
using System.Text;
using Commons.Preferences;

namespace Commons.Daos
{
	public class ObjectCacheDao<K, V> : DictionaryCacheDao<K, V>
	{
		protected Func<V, K> KeyMapper;

		public ObjectCacheDao(Func<V, K> keyMapper)
		{
			if (keyMapper == null)
				throw new ArgumentNullException("keyMapper");
			KeyMapper = keyMapper;
		}

		#region implemented abstract members of DictionaryCacheDao

		protected override K GetKey(V value)
		{
			return KeyMapper(value);
		}

		#endregion
	}

	public class DictionarybyUserCacheDao<K, V> : ICacheControl
	{
		protected Dictionary<long, DictionaryCacheDao<K, V>> d = new Dictionary<long, DictionaryCacheDao<K, V>>();

		protected Func<V, K> keyMapper;

		public DictionarybyUserCacheDao (Func<V, K> keyMapper)
		{
			if (keyMapper == null)
				throw new ArgumentNullException("keyMapper");
			this.keyMapper = keyMapper;
		}

		public virtual void Insert (long userId, V value)
		{
			CheckUser(userId);
			d[userId].Insert(value);
		}
		
		public virtual void InsertAll(long userId, IEnumerable<V> list)
		{
			CheckUser(userId);
			foreach (V value in list)
			{
				d[userId].Insert(value);
			}
		}
		
		public virtual void Update (long userId, V value)
		{
			CheckUser(userId);
			d[userId].Update(value);
		}
		
		public virtual void Delete (long userId, K key)
		{
			CheckUser(userId);
			d[userId].Delete(key);
		}
		
		public virtual void DeleteAll (long userId)
		{
			CheckUser(userId);
			d[userId].DeleteAll();
		}
		
		public virtual V Get (long userId, K key)
		{
			CheckUser(userId);
			return d[userId].Get(key);
		}
		
		public virtual IEnumerable<V> GetAll (long userId)
		{
			CheckUser(userId);
			return d[userId].GetAll();
		}
		
		public virtual void ClearCache ()
		{
			d.Clear();
		}

		protected void CheckUser(long userId)
		{
			DictionaryCacheDao<K, V> result;
			if (!d.TryGetValue(userId, out result))
				d[userId] = new ObjectCacheDao<K, V>(keyMapper);
		}
	}

	public abstract class DictionaryCacheDao<K, V> : ICacheControl
	{
		protected Dictionary<K, V> dictionary = new Dictionary<K, V>();

		protected abstract K GetKey(V value);

		public Dictionary<K, V> GetDictionary ()
		{
			return dictionary;
		}

		public virtual void Insert (V value)
		{
			dictionary[GetKey(value)] = value;
		}

		public virtual void InsertAll(IEnumerable<V> list)
		{
			foreach (V value in list)
			{
				Insert(value);
			}
		}

		public virtual void Update (V value)
		{
			dictionary[GetKey(value)] = value;
		}

		public virtual void Delete (K key)
		{
			dictionary.Remove(key);
		}

		public virtual void DeleteAll ()
		{
			dictionary.Clear();
		}

		public virtual V this[K key]
		{
			get
			{
				return Get(key);
			}
		}

		public virtual V Get (K key)
		{
			V result;
			return dictionary.TryGetValue(key, out result) ? result : default(V);
		}

		public virtual IEnumerable<V> GetAll ()
		{
			return dictionary.Values;
		}

		public virtual void ClearCache ()
		{
			dictionary.Clear();
		}
	}
}

